package balancer

import (
	"context"
	"fmt"
	"github.com/coreos/etcd/clientv3"
	"google.golang.org/grpc/grpclog"
	"strings"
	"time"
)

var serviceKey string

// Register register service with name as prefix to etcd, multi etcd addr should use ; to split
func Register(etcdAddr string, name string, addr string, ttl int64) error {
	serviceKey = fmt.Sprintf("/%s/%s/%s", schema, name, addr)

	var err error
	if cli == nil {
		cli, err = clientv3.New(clientv3.Config{
			Endpoints:   strings.Split(etcdAddr, ","),
			DialTimeout: 15 * time.Second,
		})
		if err != nil {
			return err
		}
	}

	ticker := time.NewTicker(time.Second * time.Duration(ttl))

	go func() {
		for {
			getResp, err := cli.Get(context.Background(), serviceKey)
			if err != nil {
				grpclog.Error(err)
			} else if getResp.Count == 0 {
				err = withAlive(addr, ttl)
				if err != nil {
					grpclog.Error(err)
				}
			} else {
				// do nothing
			}

			<-ticker.C
		}
	}()

	return nil
}

// 当有服务器启动时，调用etcdv3 api的put函数，更新相关信息。当服务器关机时，调用delete函数
func withAlive(serviceValue string, ttl int64) error {
	leaseResp, err := cli.Grant(context.Background(), ttl)
	if err != nil {
		return err
	}

	grpclog.Info("key:%v\n", serviceKey)
	_, err = cli.Put(context.Background(), serviceKey, serviceValue, clientv3.WithLease(leaseResp.ID))
	if err != nil {
		return err
	}

	_, err = cli.KeepAlive(context.Background(), leaseResp.ID)
	if err != nil {
		return err
	}
	return nil
}

// UnRegister remove service from etcd
func UnRegister() {
	if cli != nil {
		cli.Delete(context.Background(), serviceKey)
	}
}
